home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
ast_comp
/
gopher.lha
/
gopher1.01
/
gopherd
/
ftp.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-06-23
|
8KB
|
308 lines
/* -------------------------------------------------
* g2fd.c Gopher to FTP gateway daemon.
* Version 0.3 Hacked up: April 1992. Farhad Anklesaria.
* Based on a Perl story by John Ladwig.
* Based on a Perl story by Farhad Anklesaria.
*
* To be run by inetd.
* For installation, read the companion README.... or
* if you don't feel like doing that, the brief instructions
* are below:
*
* First edit the local parameters in defines below.
* Then do a "make g2fd"
* Then place the binary (g2fd) in some reasonable place,
* eg in /usr/local/bin
* Finally, edit /etc/services and /etc/servers or
* /etc/inetd.conf as the case may be. Kill
* and restart inetd.
*
* This file looks best with tabstops set to 4 rather than 8.
---------------------------------------------------- */
#include "gopherd.h"
#include <signal.h>
#include <stdio.h>
#define GFILE 0 /* Gopher item types */
#define GDIR 1
#define GBINHEX 4
#define GDOSB 5
#define GUNIXB 9
#define SLEN 255 /* Generic small buffer length */
#define TMOUT 1200 /* 20 minutes is plenty long enough */
char *appname;
char ftp[SLEN] = FTP;
char tmpList[SLEN] = LIST;
char tmpData[SLEN] = DATA;
char query[BUFSIZ]; /* input redirected by inetd */
char *host, *thing; /* pointers into query */
int gettingFile = 1;
int gettingBinary = 0;
int childpid;
SendFtpQuery(query)
char *query;
{
int sLen, termCh;
char *at;
FILE *fd, *popen();
if (DEBUG)
printf("The full query was %s\n", query);
if ((sLen = strlen(query)) <= 2) Abort("No host name specified.");
host = query;
at = strchr(query, '@');
if (at == NULL)
Abort("Not a valid ftp query.");
thing = at + 1;
*at = '\0'; /*Sneakily chop it into two strings*/
sprintf(ftp + strlen(ftp), " -n %s > %s", host, tmpList);
if ((fd = popen(ftp, "w")) == NULL)
Abort("Can't run ftp.");
FailErr(fprintf(fd, "user anonymous gopher@%s\n", Zehostname));
sLen = strlen(thing);
termCh = thing[sLen - 1]; /* Grab possible end char: / etc */
if ((termCh == '*') || (termCh == '@')) /* || (termCh == '/') */
thing[sLen - 1] = '\0';
if (DEBUG)
printf("At this point host: %s thing: %s\n", host, thing);
if (termCh == '/') { /* We have a directory */
gettingFile = 0;
if (strlen(thing) > 0)
FailErr(fprintf(fd, "cd \"%s\"\n", thing));
FailErr(fprintf(fd, "ls -F\n"));
}
else { /* We have a file */
gettingFile = 1;
if (gettingBinary = IsBinaryType(thing))
FailErr(fprintf(fd, "binary\n"));
FailErr(fprintf(fd, "get \"%s\" \"%s\"\n", thing, tmpData));
}
FailErr(fprintf(fd, "quit\n"));
pclose(fd);
}
/*--------------------------------*/
TranslateResults(sockfd)
{
FILE *fp, *OpenOrDie();
char buf[BUFSIZ], theName[SLEN];
int fd, nRead, checkIt;
char outputline[512];
checkIt = 1;
if (gettingFile) {
if (gettingBinary) { /* icky binary file */
if (DEBUG)
printf("Whoa! That's a binary file\n");
fd = uopen(tmpData, "r");
while ((nRead = read(fd, buf, sizeof buf)) > 0) {
writen(sockfd, buf, nRead);
}
close(fd);
} else { /* must be a nice texty file */
fp = OpenOrDie(tmpData, "r");
while (fgets(buf, sizeof buf, fp) != NULL) {
if (checkIt) { /* Just peek at it once */
checkIt = 0;
if (NotText(buf)) {
fclose(fp);
Abort("Sorry. File does not appear to contain text.");
}
}
ZapCRLF(buf);
writestring(sockfd, buf);
writestring(sockfd, "\r\n");
/*FailErr(printf("%s\r\n", buf));*/
}
fclose(fp);
FailErr(writestring(sockfd,".\r\n"));
}
} else { /* Must be a directory */
fp = OpenOrDie(tmpList, "r");
while (fgets(buf, sizeof buf, fp) != NULL) {
GopherType(buf, theName);
sprintf(outputline, "%s\tftp:%s@%s%s\t%s\t%d\r\n", theName,
host, thing, buf, Zehostname, GopherPort);
writestring(sockfd, outputline);
}
fclose(fp);
FailErr(writestring(sockfd, ".\r\n"));
}
}
/*--------------------------------*/
FILE *OpenOrDie(file, mode)
char *file, *mode;
{
FILE *fp, *fopen();
if ((fp = ufopen(file, mode)) != NULL) {
return(fp);
} else {
Abort("Could not complete the transfer.");
}
}
/*--------------------------------*/
NotText(buf)
char * buf;
{
int max; char *c;
if ((max = strlen(buf)) >= (BUFSIZ - 50)) max = BUFSIZ - 50;
for (c = buf; c < (buf + max); c++) {
if (*c > '~') return(1);
}
return(0);
}
/*--------------------------------*/
Abort(complaint)
char *complaint;
{
printf("3 Error: %s\r\n.\r\n", complaint);
Cleanup();
exit(1);
}
/*--------------------------------*/
IsBinaryType(thing)
char *thing;
{
static char *binExt[] = {
".zip", ".zoo", ".arj", ".arc", ".lzh", ".hyp", ".pak", ".exe", ".com",
".ps", ".gif", ".pict", ".pct", ".tiff", ".tif", ".tar", ".Z"
};
int extType, i;
for (extType = 0; extType < 17; extType++) {
i = strcasecmp(thing + strlen(thing) - strlen(binExt[extType]),
binExt[extType]);
if (i == 0) return(1);
}
return(0);
}
/*--------------------------------*/
GenerateUniqueFiles(tmpList, tmpData)
char *tmpList, *tmpData;
{
char *s;
int pid;
pid = getpid();
s = strchr(tmpList, '+');
sprintf(s, "%d", pid);
s = strchr(tmpData, '+');
sprintf(s, "%d", pid);
}
/*--------------------------------*/
GopherType(buf, theName)
char *buf, *theName;
{
static char ext4[] = ".hqx";
static char *ext5[] = {".zip", ".zoo", ".arj", ".arc", ".lzh", ".hyp",
".pak", ".exe", ".com", ".ps", ".gif", ".pict",
".pct", ".tiff", ".tif"};
static char *ext9[] = {".tar", ".Z"};
int extType, i, last;
char tmpName[SLEN];
last = strlen(buf) - 1; buf[last--] = '\0'; /* Munge the LF */
strcpy(tmpName, buf);
if (buf[last] == '/') {
tmpName[last] = '\0';
sprintf(theName, "%d%s", GDIR, tmpName);
return;
}
if ((buf[last] == '*') || (buf[last] == '@')) { /* Hack out * and @ */
buf[last] = '\0';
tmpName[last] = '\0';
}
/* At this point we're looking at a file */
if (strcasecmp(buf + strlen(buf) - strlen(ext4), ext4) == 0) { /* BinHex? */
sprintf(theName, "%d%s", GBINHEX, tmpName);
return;
}
for (extType = 0; extType < 15; extType++) { /* PC garbage? */
i = strcasecmp(buf + strlen(buf) - strlen(ext5[extType]),
ext5[extType]);
if (i == 0) {
sprintf(theName, "%d%s", GDOSB, tmpName);
return;
}
}
for (extType = 0; extType < 2; extType++) { /* unix binary? */
i = strcasecmp(buf + strlen(buf) - strlen(ext9[extType]),
ext9[extType]);
if (i == 0) {
sprintf(theName, "%d%s", GUNIXB, tmpName);
return;
}
}
sprintf(theName, "%d%s", GFILE, tmpName);
return; /* Some other and hopefully text file */
}
/*--------------------------------*/
Cleanup()
{
unlink(tmpList);
unlink(tmpData);
exit(1);
}
/*--------------------------------*/
RoundEmUp()
{
kill(childpid, SIGKILL);
Cleanup();
}
/*--------------------------------*/
FailErr(result)
int result;
{
if (result < 0) {
Cleanup();
}
}
/*--------------------------------*/